package importExcel

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"github.com/shopspring/decimal"
	"github.com/spf13/cast"
	"github.com/tealeg/xlsx"
	"gorm.io/gorm"
	"insighttracking/apps/admin/auth"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"io"
	"net/http"
	"path"
	"strings"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
	"insighttracking/apps/admin/internal/svc"
	"os"
)

type ImportSpuExcelApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewImportSpuExcelApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *ImportSpuExcelApiLogic {
	hostname, _ := os.Hostname()
	return &ImportSpuExcelApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *ImportSpuExcelApiLogic) ImportSpuExcelApi() (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	file, handler, err := l.Request.FormFile("file")
	if err != nil {
		return "", err
	}
	defer file.Close()
	fileType := path.Ext(handler.Filename)
	if !k.IsContains([]string{".xlsx", ".xls"}, fileType) {
		return "", errors.New("只能是.xlsx,.xls其中一种格式")
	}
	workDir, _ := os.Getwd()
	dst := path.Join(workDir, handler.Filename)
	f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("本地创建失败")
		return "", errors.New("上传文件失败")
	}
	defer f.Close()
	io.Copy(f, file)
	// 读取Excel文件内容
	xlFile, err := xlsx.OpenFile(dst)
	if err != nil {
		fmt.Println("读取excel失败", err)
		return "", errors.New("上传失败")
	}
	// 单独设置超时时间
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	for _, sheet := range xlFile.Sheets {
		fmt.Println("开始读取数据")
		for index, row := range sheet.Rows { // 循环行
			if index > 2 {
				//for _, cell := range row.Cells { // 循环每列
				//	// 获取单元格的值并输出
				//	fmt.Printf("%s\t", cell.String())
				//}
				//fmt.Println()
				if len(row.Cells) == 0 {
					break
				}
				name := row.Cells[0].String()
				categoryName1 := row.Cells[1].String()
				categoryName2 := row.Cells[2].String()
				categoryName3 := row.Cells[3].String()
				unit := row.Cells[4].String()
				isWeighed := row.Cells[5].String()
				salesPrice := row.Cells[6].String()
				status := row.Cells[7].String()
				supplier := row.Cells[8].String()
				brand := row.Cells[9].String()
				lossRate := row.Cells[10].String()
				purchasePrice := row.Cells[11].String()
				logx.WithContext(l.ctx).Infof("当前行数据:(name=%s,categoryName1=%s,categoryName2=%s,categoryName3=%s,unit=%s,isWeighed=%s,salesPrice=%s,status=%s,supplier=%s,brand=%s,lossRate=%s,purchasePrice=%s)",
					name, categoryName1, categoryName2, categoryName3, unit, isWeighed, salesPrice, status, supplier, brand, lossRate, purchasePrice)
				var categoryId int64
				var categoryIdList = make([]string, 0)
				var categoryName = ""
				if categoryName1 == "" {
					return "", errors.New("导入失败！一级分类必填")
				} else {
					categoryEntity, err := service.CategoryService.GetByNameApi(ctx, accountInfo.EnterpriseId, categoryName1)
					if errors.Is(err, gorm.ErrRecordNotFound) {
						return "", errors.New("导入失败！分类字段导入有误")
					}
					categoryId = categoryEntity.ID
					categoryIdList = append(categoryIdList, cast.ToString(categoryEntity.ID))
					categoryName = categoryName1
				}

				if categoryName2 != "" {
					categoryEntity, err := service.CategoryService.GetByNameApi(ctx, accountInfo.EnterpriseId, categoryName2)
					if errors.Is(err, gorm.ErrRecordNotFound) {
						return "", errors.New("导入失败！分类字段导入有误")
					}
					categoryId = categoryEntity.ID
					categoryIdList = append(categoryIdList, cast.ToString(categoryEntity.ID))
					categoryName = categoryName2
				}
				if categoryName3 != "" {
					categoryEntity, err := service.CategoryService.GetByNameApi(ctx, accountInfo.EnterpriseId, categoryName2)
					if errors.Is(err, gorm.ErrRecordNotFound) {
						return "", errors.New("导入失败！分类字段导入有误")
					}
					categoryId = categoryEntity.ID
					categoryIdList = append(categoryIdList, cast.ToString(categoryEntity.ID))
					categoryName = categoryName3
				}
				var unitId int64
				if unit == "" {
					return "", errors.New("导入失败！单位字段导入有误")
				} else {
					unitEntity, err := service.UnitService.GetByNameApi(ctx, accountInfo.EnterpriseId, unit)
					if errors.Is(err, gorm.ErrRecordNotFound) {
						return "", errors.New("导入失败！单位字段导入有误")
					}
					unitId = unitEntity.ID
				}
				if isWeighed == "" {
					return "", errors.New("导入失败！是否字段导入有误")
				} else {
					if isWeighed != "0" && isWeighed != "1" {
						return "", errors.New("导入失败！是否字段导入有误")
					}
				}
				salesPriceDecimal := decimal.Zero
				if salesPrice == "" {
					return "", errors.New("导入失败！销售单价字段导入有误")
				} else {
					salesPriceDecimal, err = decimal.NewFromString(salesPrice)
					if err != nil {
						return "", errors.New("导入失败！销售单价字段导入有误")
					}
				}
				if status == "" {
					return "", errors.New("导入失败！状态字段导入有误")
				} else {
					if status != "0" && status != "1" {
						return "", errors.New("导入失败！状态字段导入有误")
					}
				}
				var supplierId int64
				if supplier == "" {
					return "", errors.New("导入失败！供应商字段导入有误")
				} else {
					supplierEntity, err := service.SupplierService.GetByNameApi(l.ctx, accountInfo.EnterpriseId, supplier)
					if errors.Is(err, gorm.ErrRecordNotFound) {
						return "", errors.New("导入失败！供应商字段导入有误")
					}
					supplierId = supplierEntity.ID
				}
				purchasePriceDecimal := decimal.Zero
				if purchasePrice == "" {
					return "", errors.New("导入失败！采购指导价字段导入有误")
				} else {
					purchasePriceDecimal, err = decimal.NewFromString(purchasePrice)
					if err != nil {
						return "", errors.New("导入失败！采购指导价字段导入有误")
					}
				}
				var brandId int64
				if brand != "" {
					brandEntity, err := service.BrandService.GetByNameApi(ctx, accountInfo.EnterpriseId, brand)
					if errors.Is(err, gorm.ErrRecordNotFound) {
						return "", errors.New("导入失败！品牌字段导入有误")
					}
					brandId = brandEntity.ID
				}
				lossRateDecimal, err := decimal.NewFromString(lossRate)
				if err != nil {
					return "", errors.New("导入失败！损耗率字段导入有误")
				}
				if err = service.SpuService.CreateApi(ctx, &model.SpuEntity{
					EnterpriseID:   accountInfo.EnterpriseId,          // 关联到enterprise表主键id
					SpuType:        0,                                 // 商品类型,0表示基础商品,1表示加工商品
					Name:           name,                              // 商品名称
					CategoryID:     categoryId,                        // 商品分类,只保存最后一级的
					CategoryName:   categoryName,                      // 单位分类名称
					CategoryIDList: strings.Join(categoryIdList, ","), // 分类列表,多个用英文,拼接
					UnitID:         unitId,                            // 单位,关联到unit表主键id
					IsWeighed:      cast.ToInt64(isWeighed),           // 是否称重,0表示是,1表示否
					SalesPrice:     salesPriceDecimal,                 // 销售价
					Status:         cast.ToInt64(status),              // 上架状态:1是上架,2是下架
					SupplierID:     supplierId,                        // 供应商id
					BrandID:        brandId,                           // 品牌id
					LossRate:       lossRateDecimal,                   // 损耗率
					PurchasePrice:  purchasePriceDecimal,              // 采购价格
				}); err != nil {
					logx.WithContext(l.ctx).Infof("创建商品失败:%v", err)
					return "", errors.New("导入失败！导入有误")
				}
			}
		}
	}
	if err = os.Remove(dst); err != nil {
		fmt.Println("删除文件失败", err)
	}
	fmt.Println(dst, "?")
	return "上传成功", nil
}
